package plp.orientadaObjetos2.reflection;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import plp.orientadaObjetos1.declaracao.procedimento.DecProcedimento;
import plp.orientadaObjetos1.declaracao.variavel.DecVariavel;
import plp.orientadaObjetos2.ProgramaOO2;
import plp.orientadaObjetos2.declaracao.classe.DecClasseSimplesOO2;

public class ClasseReflection {
	
	private List<DecClasseSimplesOO2> listaDeClasses;
	private ProgramaOO2 programa;
	
	public ClasseReflection(ProgramaOO2 programa) {
		this.listaDeClasses = new ArrayList<DecClasseSimplesOO2>();
		this.programa = programa;
		adicionarClasseParaListaDeClasses();
	}
	
	/**
	 * Busca a classe que teve seu nome passado como parametro de 
	 * pesquisa em um repositorio de classes instanciadas no programa.
	 * @param nomeClasse
	 * @return classe.: retorna uma instancia de DecClasseSimplesOO2
	 */
	public DecClasseSimplesOO2 getClasse(String nomeClasse) {
		for (DecClasseSimplesOO2 classe: listaDeClasses) {
			if (classe.getNomeClasse().equals(nomeClasse)) {
				return classe;
			}
		}
		return null;
	}
	
	/**
	 * Varre e adiciona os metodos da classe a um HashMap.
	 * @return listaDeMetodos
	 */
	public HashMap<String, DecProcedimento> getMetodosDeclarados() {
		HashMap<String, DecProcedimento> listaDeMetodos = new HashMap<String, DecProcedimento>();
		for (DecClasseSimplesOO2 classe: this.listaDeClasses) {
			listaDeMetodos.put(classe.getNomeClasse(), classe.getMetodos());
		}
		return listaDeMetodos;
	}
	
	/**
	 * Varre e adiciona os atributos da classe a um HashMap.
	 * @return listaDeAtributos
	 */
	public HashMap<String, DecVariavel> getAtributosDeclarados() {
		HashMap<String, DecVariavel> listaDeAtributos = new HashMap<String, DecVariavel>();
		for (DecClasseSimplesOO2 classe: this.listaDeClasses) {
			listaDeAtributos.put(classe.getNomeClasse(), classe.getAtributos());
		}
		return listaDeAtributos;
	}
	
	private void adicionarClasseParaListaDeClasses() {
		if (this.programa.getDecClasse() instanceof DecClasseSimplesOO2) {
			this.listaDeClasses.add((DecClasseSimplesOO2) this.programa.getDecClasse());
		} // implementar com DecClasseComposta
	}

}
